package com.om.pages;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;



import com.om.base.AbstractBean;
import com.om.base.BeanFactory;
import com.om.base.SqlFilter;
import com.om.base.Utils;
import com.om.common.ConfigReader;

/**
 * 针对于指定的AbstractBean类进行分页查询工具
 * @author tangchuan
 *
 */
public class DataPageUtils {

	public static String TemplatePath = "";
	public static String PageNoField = "pageNo";
	public static String PageSizeField = "pageSize";
	public static String OrderByField = "orderBy";
	public static String OrderDirField = "orderdir";
	public static String OrderByColField ="orderByCol";
	
	
	public String templateName = "pagefoot.json";
	public String pageFootJsonTemplate = "";
	public String dataRowJsonTemplate = "";
	public String fieldPrefix = "";
	
	/**
	 * 当前查询的实体类的Class
	 */
	public Class<?> beanClass = null;
	
	
	/**
	 * 记录的总条数
	 */
	public int allCount = 0;
	/**
	 * 分页的大小
	 */
	public int pageSize = 20;
	/**
	 * 总页数
	 */
	public int pageCount = 0;
	/**
	 * 当前的页号
	 */
	public int pageNo = 1;
	
	/**
	 * 排序的语句
	 */
	public String orderBy = "";
	
	public AbstractBean bean = null;
	/**
	 * 当前操作的BeanFactory对象
	 */
	public BeanFactory factory = null;
	/**
	 * 当前查询使用的数据库连接对象
	 */
	public Connection connection = null;
	
	private HttpServletRequest request = null;

	public String pageNoField = "";
	public String pageSizeField = "";
	public String orderByField = "";
	public String orderDirField = "";
	public String orderByColField ="";

	public String prefix = "";
	public boolean generateFilter = false;
	/**
	 * 查询排序的字段列表，多个字段用逗号分隔
	 */
	public String orderByCol = "";
	/**
	 * 排序的方向,asc,desc
	 */
	public String orderByDirection = " asc ";
	
	

	
	/**
	 * 构造函数
	 * @param modelClass 查询关联的对象的Class
	 * @param req 当前请求的对象句柄
	 */
	public DataPageUtils(Class modelClass, HttpServletRequest req) {
		this.beanClass = modelClass;
		this.request = req;
		this.loadTemplate();
	}
	
	/**
	 * 构造函数
	 * @param modelClass 查询关联的对象的Class
	 * @param req 当前请求的对象句柄
	 * @param templateName 查询使用的分页信息模板
	 */
	public DataPageUtils(Class modelClass, HttpServletRequest req,
			String templateName) {
		this.beanClass = modelClass;
		this.templateName = templateName;
	}
	
	/**
	 * 构造函数
	 * @param modelClass 查询关联的对象的Class
	 * @param req 当前请求的对象句柄
	 * @param templateName 查询使用的分页信息模板
	 * @param con 数据库连接
	 */
	public DataPageUtils(Class modelClass, HttpServletRequest req,
			String templateName, Connection con) {
		this.beanClass = modelClass;
		this.templateName = templateName;
		this.connection = con;
	}

	
	/**
	 * 根据查询条件、分页编号、分页尺寸、排序字段进行分页查询
	 * @param filter 过滤条件
	 * @param pageSize 分页的尺寸
	 * @param pageNo 分页编号
	 * @param orderBy 排序字段列表，过个字段间通过逗号分隔
	 * @param loadChild 是否加载与当前对象关联的子表数据
	 * @return 含有查询结果以及分页信息的结果集合
	 */
	public RecordPage fetch(SqlFilter filter, int pageSize, int pageNo,
			String orderBy,boolean loadChild) {
		RecordPage recordPage = new RecordPage();
		try {

			PageInfo page = new PageInfo();
			List<AbstractBean> rows = new ArrayList<AbstractBean>();

			if (this.connection == null) {
				this.connection = Utils.GetOpenedConnection();
			}

			this.factory = BeanFactory.GenerateFactory(beanClass,
					this.connection);
			this.orderBy = orderBy;
			if (this.orderBy == null || "".equals(this.orderBy)) {
				orderBy= " order by " + this.factory.bean.PrimaryKey
						+ " desc ";
			}
			this.allCount = factory.getRecordCount(filter.clone());
			if (pageSize == 0) {
				pageSize = allCount;
			} 
			
			this.pageCount = this.allCount / pageSize;
			if (allCount % pageSize != 0) {
				this.pageCount = this.pageCount + 1;
			}
			
			if(pageNo<0){
				pageNo=0;
			}
			if(pageNo>pageCount){
				pageNo=pageCount;
			}
			page.currentPage = pageNo<=pageCount?(pageNo - 1):(pageCount-1);
			if(page.currentPage <0){
				page.currentPage =0;
			}
			
			page.pageSize = pageSize;
			page.realSize = pageSize;
			page.pageNo = pageNo;
			page.allCount = this.allCount;
			page.pageCount = this.pageCount;
			page.first = !(page.currentPage == 0);
			page.fornt = page.first;
			page.next = !(page.currentPage >= page.pageCount - 1);
			page.last = page.next;
			page.orderBy = orderBy;
			
			rows = factory.getBeanList(this.beanClass, filter, page);
			if(loadChild){
				for(int i=0;i<rows.size();i++ ){
					rows.get(i).loadAllChildren();
				}
			}
			page.rowCount = rows.size();
			recordPage.items = rows;
			recordPage.pageCtrl = page;

		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return recordPage;
	}
	
	/**
	 * 根据查询条件、分页编号、分页尺寸、排序字段进行分页查询
	 * 当前方法会自动读取request对象中的pageNo参数作为分页编号
	 * 读取orderByCol参数作为排序的字段列表
	 * 读取orderdir参数作为排序的方向
	 * @param filter 过滤条件
	 * @param loadChild 是否加载与当前对象关联的子表数据
	 * @return 含有查询结果以及分页信息的结果集合
	 */
	public RecordPage fetch(SqlFilter filter,String orderBy,boolean loadChild) {
		RecordPage recordPage = new RecordPage();
		try {

			String orderValue = " desc ";
			String strOrderBy = "";
			
			
			if("".equals(this.pageSizeField)){
				this.pageSizeField = DataPageUtils.PageSizeField;
			}
			if("".equals(this.pageNoField)){
				this.pageNoField = DataPageUtils.PageNoField;
			}
			
			
			
			

			//pageSize
			int realPageSize = this.pageSize;
			if (!"".equals(Utils.GetParameter(this.request, this.pageSizeField))) {
				realPageSize = Integer.valueOf(
						Utils.GetParameter(this.request, this.pageSizeField))
						.intValue();
			}
			
			//pageNo
			int pageNo = 1;
			String currentPage = Utils.GetParameter(this.request,this.pageNoField);
			if (!"".equals(currentPage) && Integer.parseInt(currentPage)>=1) {
				pageNo = Integer.parseInt(currentPage) ;
			}
			recordPage = this.fetch(filter, realPageSize, pageNo, orderBy,loadChild);

		} catch (Exception ex) {
			ex.printStackTrace();
			
		}
		return recordPage;
	}
	public RecordPage fetch(SqlFilter filter,boolean loadChild) {
		RecordPage recordPage = new RecordPage();
		try {

			String orderValue = " desc ";
			String strOrderBy = "";
			
			
			if("".equals(this.pageSizeField)){
				this.pageSizeField = DataPageUtils.PageSizeField;
			}
			if("".equals(this.pageNoField)){
				this.pageNoField = DataPageUtils.PageNoField;
			}
			if("".equals(this.orderByField)){
				this.orderByField = DataPageUtils.OrderByField;
			}
			if("".equals(this.orderDirField)){
				this.orderDirField = DataPageUtils.OrderDirField;
			}
			if("".equals(this.orderByColField)){
				this.orderByColField = DataPageUtils.OrderByColField;
			}
			
			
			if (!(this.orderByCol.equals(""))) {
				strOrderBy = " order by " + this.orderByCol + " " + orderValue;
			} else if (!(this.orderBy.equals(""))) {
				strOrderBy = this.orderBy;
			}

			//pageSize
			int realPageSize = this.pageSize;
			if (!"".equals(Utils.GetParameter(this.request, this.pageSizeField))) {
				realPageSize = Integer.valueOf(
						Utils.GetParameter(this.request, this.pageSizeField))
						.intValue();
			}
			//orderByDirection
			if (!"".equals(Utils.GetParameter(this.request, this.orderDirField))) {
				this.orderByDirection = Utils.GetParameter(this.request, this.orderDirField);
				if (this.orderByDirection.trim().equals("")) {
					orderValue = " asc ";
				} else if (this.orderByDirection.trim().equals("asc")) {
					orderValue = " asc ";
				} else if (this.orderByDirection.trim().equals("desc")) {
					orderValue = " desc ";
				}
			}
			//pageNo
			int pageNo = 1;
			String currentPage = Utils.GetParameter(this.request,this.pageNoField);
			if (!"".equals(currentPage) && Integer.parseInt(currentPage)>=1) {
				pageNo = Integer.parseInt(currentPage) ;
			}
			
			
			if (!"".equals(Utils.GetParameter(this.request, this.orderByColField))) {
				this.orderByCol = Utils.GetParameter(this.request, this.orderByColField);
			}
			if(!"".equals(this.orderByCol)){
				strOrderBy = " order by "+orderByCol+" "+orderByDirection;
			}
			else{
				AbstractBean bean = (AbstractBean)BeanFactory.LoadBean(this.beanClass);
				strOrderBy = " order by "+bean.PrimaryKey+" Desc";
			}
			 
			
			recordPage = this.fetch(filter, realPageSize, pageNo, strOrderBy,loadChild);

		} catch (Exception ex) {
			ex.printStackTrace();
			
		}
		return recordPage;

	}

	

	private void loadTemplate() {

		try {
			String fileName = this.templateName;
			//String filePath = TemplatePath + fileName;
			String templatePath = ConfigReader.GetProptery("template.path") ;
			if(!templatePath.equals("")){
				String filePath = ConfigReader.GetProptery("template.path") + fileName;

				if (this.pageFootJsonTemplate == null
						|| "".equals(this.pageFootJsonTemplate)) {
					this.pageFootJsonTemplate = Utils.ReadFileByLines(filePath,
							"utf8");
				}
			}
			
		} catch (Exception ex) {
			ex.printStackTrace();
		}

	}

}
